package com.huilian.test.pdf;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.pdf.BaseFont;
import fr.opensagres.odfdom.converter.pdf.PdfOptions;
import fr.opensagres.xdocreport.converter.ConverterTypeTo;
import fr.opensagres.xdocreport.converter.Options;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.ByteArrayImageProvider;
import fr.opensagres.xdocreport.document.images.IImageProvider;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.itext.extension.font.IFontProvider;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class OdtToPdf {

    final public static Logger log = LoggerFactory.getLogger(OdtToPdf.class);

    private static final String FONTS_SONGTI = "宋体";

    public static final String FONTS_MANGAL = "Mangal";

    public static final String FONTS_LIBERATION = "Liberation Serif";
    // 字体缓冲
    private byte[] nsimsunByte = null;
    private byte[] mangalByte = null;
    private byte[] liberationserifByte = null;

    private static IFontProvider fontProvide = null;


    public void init(){
        log.info("OdtToPdf.init()");
        try {
            nsimsunByte = IOUtils.resourceToByteArray("/fonts/NSimSun-02.ttf");
            mangalByte = IOUtils.toByteArray(OdtToPdf.class.getResourceAsStream("/fonts/mangal.ttf"));
            liberationserifByte = IOUtils.toByteArray(OdtToPdf.class.getResourceAsStream("/fonts/LiberationSerif-Regular.ttf"));
        } catch (IOException e) {
            log.error("OdtToPdf.init error",e);
        }
        this.fontProvide =(familyName, encoding, size, style, color) -> {
            try {
                if (familyName.equalsIgnoreCase(FONTS_SONGTI)) {
                    BaseFont baseFont =BaseFont.createFont("NSimSun-02.ttf", encoding, BaseFont.EMBEDDED, true, nsimsunByte, null);
                    return new Font(baseFont, size, style, color);
                }
                if (familyName.equalsIgnoreCase(FONTS_MANGAL)) {
                    BaseFont baseFont =
                            BaseFont.createFont("mangal.ttf", encoding, BaseFont.EMBEDDED,true,mangalByte, null);
                    return new Font(baseFont, size, style, color);
                }
                if (familyName.equalsIgnoreCase(FONTS_LIBERATION)) {
                    BaseFont baseFont = BaseFont.createFont("LiberationSerif-Regular.ttf", encoding, BaseFont.EMBEDDED,true,liberationserifByte, null);
                    return new Font(baseFont, size, style, color);
                }
            } catch (Exception e) {
                log.error("OdtToPdf.init error",e);
                throw new RuntimeException(e);
            }
            return FontFactory.getFont(familyName, encoding, size, style, color);
        };
    }

    /**
     * doc转pdf
     * @return
     */
    public static byte[] wordToPDF(Map<String,String> fillDataMap, byte[] sourcePdfFileByte) {
        Map<String,Object> params = new HashMap<>();
        fillDataMap.forEach((k,v)->{
            JSONArray jsonArray = isJsonArray(v);
            if(jsonArray != null){
                for(int i=0;i<jsonArray.size();i++){
                    Map<String,Object> jsonObject =(Map<String, Object>) jsonArray.get(i);
                    jsonObject.forEach((key,val)->{
                            jsonObject.put(key,val);

                    });
                }
                params.put(k,jsonArray);
            }else{
                params.put(k,v);
            }
        });
        try (InputStream in = new ByteArrayInputStream(sourcePdfFileByte);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Velocity);
            IContext context = report.createContext();
            context.putMap(params);
            FieldsMetadata metadata = report.createFieldsMetadata();
            for (Map.Entry<String, Object> o : context.getContextMap().entrySet()) {
                if (o.getValue() instanceof Iterable) {
                    metadata.addFieldAsList(o.getKey());
                }else if(o.getValue() instanceof  InputStream){
                    metadata.addFieldAsImage(o.getKey());
                    IImageProvider imageProvider = new ByteArrayImageProvider((InputStream) o.getValue());
                    imageProvider.setResize(true);
                    context.put(o.getKey(), imageProvider);
                }
            }
            //可转换为 html fo pdf等格式
            Options options = Options.getTo(ConverterTypeTo.PDF);
            PdfOptions pdfOptions = PdfOptions.create();
            pdfOptions.fontProvider(fontProvide);
            options.subOptions(pdfOptions);
            report.convert(context, options, outputStream);
            return outputStream.toByteArray();
        } catch (Exception e) {
            log.error("word2pdf . wordToPDF fail, errorMsg: " + e.getMessage(), e);
            return null;
        }
    }


    private static JSONArray isJsonArray(String jsonStr){
        try {
            if(jsonStr.startsWith("[{")){
                JSONArray array = JSON.parseArray(jsonStr);
                return array;
            }
        }catch (Exception e){
            return null;
        }
        return null;
    }

    public static void main(String[] args) throws IOException {
        Map<String,String> fillDataMap =new HashMap<>();
        fillDataMap.put("customerRealName","张宁");

        OdtToPdf odtToPdf =new OdtToPdf();
        odtToPdf.init();
        //只支持odt
        String filepath = "F:\\待办\\20191213勋之洛线上合同\\借款合同\\个人借款合同.odt";
        String outpath = "F:\\待办\\20191213勋之洛线上合同\\借款合同\\个人借款合同.pdf";

        byte[] source = IOUtils.toByteArray(new FileInputStream(filepath));

        byte[]  target = odtToPdf.wordToPDF(fillDataMap,source);
        IOUtils.write(target, new FileOutputStream(outpath));

    }
}